package com.xxxtea.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxtea.common.Result;
import com.xxxtea.common.UserContext;
import com.xxxtea.dto.PageQuery;
import com.xxxtea.entity.Dish;
import com.xxxtea.entity.OrderItem;
import com.xxxtea.entity.Review;
import com.xxxtea.entity.User;
import com.xxxtea.service.DishService;
import com.xxxtea.service.OrderItemService;
import com.xxxtea.service.ReviewService;
import com.xxxtea.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 评价控制器
 *
 * 提供评价的完整管理功能，包括：
 * - 评价的增删改查
 * - 评价与订单、用户、商品的关联
 * - 分页与列表查询
 * - 评价统计与评分更新
 *
 * 使用Swagger注解进行API文档生成
 * 使用Lombok注解简化代码
 *
 * @author badman
 * @since 1.0.0
 */
@Slf4j
@Api("评价接口")
@RestController
@RequestMapping("/review")
public class ReviewController {
	/**
	 * 用户服务
	 */
	@Resource
	private UserService userService;
	
	/**
	 * 菜品服务
	 */
	@Resource
	private DishService dishService;
	
	/**
	 * 评价服务
	 */
	@Resource
	private ReviewService reviewService;
	
	/**
	 * 订单项服务
	 */
	@Resource
	private OrderItemService orderItemService;

	/**
	 * 新增评价
	 * 新增后自动更新订单子项和商品评分
	 *
	 * @param request 评价信息
	 * @return 操作结果
	 */
	@PostMapping
	@ApiOperation("新增评价")
	public Result<String> save(@RequestBody Review request) {
		if (!reviewService.save(request)) {
			return Result.error("添加失败!");
		}
		// 更新订单子项为已评价
		orderItemService.lambdaUpdate().eq(OrderItem::getBusinessType, request.getBusinessType())
				.eq(OrderItem::getBusinessId, request.getBusinessId())
				.set(OrderItem::getReviewId, request.getId())
				.update();
		reviewService.calRating(request.getBusinessId(), request.getBusinessType());
		return Result.success();
	}

	/**
	 * 删除评价
	 *
	 * @param id 评价ID
	 * @return 操作结果
	 */
	@DeleteMapping("/{id}")
	@ApiOperation("删除评价")
	public Result<String> removeById(@PathVariable String id) {
		if (!reviewService.removeById(id)) {
			return Result.error("删除失败!");
		}
		return Result.success();
	}

	/**
	 * 更新评价
	 *
	 * @param request 评价信息
	 * @return 操作结果
	 */
	@PutMapping
	@ApiOperation("更新评价")
	public Result<String> updateById(@RequestBody Review request) {
		if (!reviewService.updateById(request)) {
			return Result.error("更新失败!");
		}
		return Result.success();
	}

	/**
	 * 查询评价详情
	 *
	 * @param id 评价ID
	 * @return 评价详情
	 */
	@GetMapping("/{id}")
	@ApiOperation("查询评价详情")
	public Result<Review> getById(@PathVariable String id) {
		return Result.success(reviewService.getById(id));
	}

	/**
	 * 查询评价列表
	 *
	 * @param request 查询条件
	 * @return 评价列表
	 */
	@GetMapping("/list")
	@ApiOperation("查询评价列表")
	public Result<List<Review>> list(Review request) {
		LambdaQueryWrapper<Review> wrapper = new LambdaQueryWrapper<>(request);
		return Result.success(reviewService.list(wrapper));
	}

	/**
	 * 分页查询评价
	 * 支持按业务类型、商家角色等条件筛选，并补充用户信息
	 *
	 * @param request 分页查询条件
	 * @return 分页评价列表
	 */
	@PostMapping("/page")
	@ApiOperation("分页查询评价")
	public Result<Page<Review>> page(@RequestBody PageQuery<Review> request) {
		Review param = request.getParam();
		LambdaQueryWrapper<Review> wrapper = new LambdaQueryWrapper<>(param);
		wrapper.eq(param.getBusinessType() != null, Review::getBusinessType, param.getBusinessType());
		wrapper.orderByDesc(Review::getId);
		if (param.getBusinessType() == Review.BusinessType.DISH && UserContext.getRole() == User.Role.MERCHANT) {
			Set<Integer> dishIds = dishService.list().stream().map(Dish::getId).collect(Collectors.toSet());
			wrapper.in(Review::getBusinessId, dishIds.isEmpty() ? Collections.singleton(-1) : dishIds);
		}

		Page<Review> pageResult = reviewService.getBaseMapper().pageBusiness(request.toPage(), wrapper);
		Map<Integer, User> userMap = userService.list().stream().collect(Collectors.toMap(User::getId, Function.identity()));
		for (Review record : pageResult.getRecords()) {
			User user = userMap.get(record.getUserId());
			if (user == null) {
				continue;
			}
			record.setUserName(user.getNickname());
			if (user.getAvatar() != null) {
				record.setUserAvatar(user.getAvatar().getUrl());
			}
		}
		return Result.success(pageResult);
	}
}